package com.shxzz.easy12306.services.ticket.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.shxzz.easy12306.framework.starter.cache.StringRedisTemplateProxy;
import com.shxzz.easy12306.services.ticket.common.constant.RedisKeyConstant;
import com.shxzz.easy12306.services.ticket.common.constant.TicketConstant;
import com.shxzz.easy12306.services.ticket.common.enums.RegionStationQueryTypeEnum;
import com.shxzz.easy12306.services.ticket.dao.entity.RegionDO;
import com.shxzz.easy12306.services.ticket.dao.entity.StationDO;
import com.shxzz.easy12306.services.ticket.dao.mapper.RegionMapper;
import com.shxzz.easy12306.services.ticket.dao.mapper.StationMapper;
import com.shxzz.easy12306.services.ticket.dto.req.RegionStationQueryReqDTO;
import com.shxzz.easy12306.services.ticket.dto.resp.RegionStationQueryRespDTO;
import com.shxzz.easy12306.services.ticket.dto.resp.StationQueryRespDTO;
import com.shxzz.easy12306.services.ticket.service.RegionStationService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.shxzz.easy12306.services.ticket.common.enums.RegionStationQueryTypeEnum.*;

/**
 * 地区站点信息服务层实现
 * @author shxzz
 * @create 2024-03-13-14:33
 */
@RequiredArgsConstructor
@Service
public class RegionStationServiceImpl implements RegionStationService {

    private final StationMapper stationMapper;
    private final RegionMapper regionMapper;
    private final StringRedisTemplateProxy stringRedisTemplateProxy;

    @Override
    public List<RegionStationQueryRespDTO> listRegionStation(RegionStationQueryReqDTO requestParam) {
        if(CharSequenceUtil.isNotBlank(requestParam.getName())) {
            return getStationInfo(requestParam.getName());
        }

        String regionInfoListStr = stringRedisTemplateProxy.safeGet(
                RedisKeyConstant.REGION_OR_STATION_NAME_INFO_PREFIX + requestParam.getQueryType(),
                String.class,
                () -> {
                    LambdaQueryWrapper<RegionDO> queryWrapper= null;
                    switch(RegionStationQueryTypeEnum.getByType(requestParam.getQueryType())) {
                        case HOT -> queryWrapper = Wrappers.lambdaQuery(RegionDO.class).eq(RegionDO::getPopularFlag, 1);
                        case A_E -> queryWrapper = Wrappers.lambdaQuery(RegionDO.class).in(RegionDO::getInitial, A_E.getSpells());
                        case F_J -> queryWrapper = Wrappers.lambdaQuery(RegionDO.class).in(RegionDO::getInitial, F_J.getSpells());
                        case K_O -> queryWrapper = Wrappers.lambdaQuery(RegionDO.class).in(RegionDO::getInitial, K_O.getSpells());
                        case P_T -> queryWrapper = Wrappers.lambdaQuery(RegionDO.class).in(RegionDO::getInitial, P_T.getSpells());
                        case U_Z -> queryWrapper = Wrappers.lambdaQuery(RegionDO.class).in(RegionDO::getInitial, U_Z.getSpells());
                    }
                    List<RegionDO> regionDOList = regionMapper.selectList(queryWrapper);
                    return JSON.toJSONString(BeanUtil.copyToList(regionDOList, RegionStationQueryRespDTO.class));
                },
                TicketConstant.ADVANCED_QUERY_TICKET_DAY,
                TimeUnit.DAYS
        );

        return JSON.parseArray(regionInfoListStr, RegionStationQueryRespDTO.class);
    }

    @Override
    public List<StationQueryRespDTO> listAllStation() {
        String stationInfoListStr = stringRedisTemplateProxy.safeGet(
                RedisKeyConstant.ALL_STATION_NAME_INFO ,
                String.class,
                () -> {
                    List<StationDO> stationDOList = stationMapper.selectList(Wrappers.emptyWrapper());
                    return JSON.toJSONString(BeanUtil.copyToList(stationDOList, StationQueryRespDTO.class));
                },
                TicketConstant.ADVANCED_QUERY_TICKET_DAY,
                TimeUnit.DAYS
        );
        return JSON.parseArray(stationInfoListStr, StationQueryRespDTO.class);
    }

    private List<RegionStationQueryRespDTO> getStationInfo(String name) {
        String stationInfoListStr = stringRedisTemplateProxy.safeGet(
                RedisKeyConstant.REGION_OR_STATION_NAME_INFO_PREFIX + name,
                String.class,
                () -> {
                    LambdaQueryWrapper<StationDO> queryWrapper = Wrappers.lambdaQuery(StationDO.class)
                            .likeRight(StationDO::getName, name)
                            .or()
                            .likeRight(StationDO::getSpell, name);
                    List<StationDO> stationDOList = stationMapper.selectList(queryWrapper);
                    return JSON.toJSONString(BeanUtil.copyToList(stationDOList, RegionStationQueryRespDTO.class));
                },
                TicketConstant.ADVANCED_QUERY_TICKET_DAY,
                TimeUnit.DAYS
        );
        return JSON.parseArray(stationInfoListStr, RegionStationQueryRespDTO.class);
    }
}
